home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / CNews / Source / relay / hdrparse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-23  |  3.0 KB  |  115 lines

  1. /*
  2.  * Usenet header parsing and remembering.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <sys/types.h>
  8. #include "libc.h"
  9. #include "news.h"
  10. #include "control.h"
  11. #include "case.h"
  12. #include "fileart.h"
  13. #include "headers.h"
  14. #include "hdrint.h"
  15.  
  16. #define RFC1036                /* alters hdrparse behaviour */
  17.  
  18. /*
  19.  * Parse (assumed) RFC822 or 850/1036 header in "line" (ishdr(line) can
  20.  * verify this) into "hdrs" using hdrlst set of keywords by retaining the
  21.  * value of any matching keyword.  Keyword matching is case-insensitive.
  22.  * If the keyword in "line" matches one in hdrlst, store the value in
  23.  * *malloc'ed memory* (N.B.) pointed to by a member of "hdrs".
  24.  * freeheader() will free this memory.
  25.  */
  26. int                    /* NO, YES or YES+1 (error) */
  27. hdrparse(hdrs, line, hdrlst)
  28. register struct headers *hdrs;
  29. char *line;
  30. hdrlist hdrlst;                /* headers of positive utility */
  31. {
  32.     register struct hdrdef **hpp;
  33.     register char *hackline = hackhybrid(line);
  34.     register int match = NO;
  35.  
  36.     for (hpp = hdrlst; *hpp != NULL; hpp++) {
  37.         register char *hdrnm = (*hpp)->hdrnm;
  38.  
  39.         if (CISTREQN(hackline, hdrnm, (int)(*hpp)->hdrlen) &&
  40.             (*hpp)->hdroff >= 0        /* paranoia */
  41. #ifdef RFC1036
  42.             && hackline[(*hpp)->hdrlen] == ' '
  43. #endif
  44.             ) {
  45.             match = YES;
  46.             break;
  47.         }
  48.     }
  49.     if (match) {
  50.         register char **ptrp = (char **)((char *)hdrs+(*hpp)->hdroff);
  51.  
  52.         if (*ptrp != NULL && hdrlst == reqdhdrs)
  53.             match = YES+1;        /* duplicate req'd hdr */
  54.         else {
  55.             nnfree(ptrp);    /* free prev. value in this article */
  56.             *ptrp = strsave(skipsp(&hackline[(*hpp)->hdrlen]));
  57.             if (*ptrp != NULL)
  58.                 trim(*ptrp);    /* cut trailing \n */
  59.         }
  60.     }
  61.     free(hackline);
  62.     return match;
  63. }
  64.  
  65. /*
  66.  * default missing header values
  67.  *
  68.  * If strsave ever returns NULL on failure, instead of exiting,
  69.  * then the strsave calls need to check for failure.
  70.  *
  71.  * An article lacking a Message-ID: but possessing an (obsolete)
  72.  * Article-I.D.: gets the transformed Article-I.D. as its Message-ID:.
  73.  *
  74.  * We support control message *backwards* compatibility: if no Control:
  75.  * header exists and the newsgroup matches all.all.ctl, use the Subject:
  76.  * as the control message.  Ugh.
  77.  */
  78. void
  79. hdrdeflt(hdrs)
  80. register struct headers *hdrs;
  81. {
  82.     if (hdrs->h_distr == NULL)
  83.         hdrs->h_distr = strsave(DEFDIST);
  84.     if (hdrs->h_msgid == NULL && hdrs->h_artid != NULL)
  85.         hdrs->h_msgid = str3save("<", hdrs->h_artid, ">");
  86.     if (hdrs->h_expiry == NULL || hdrs->h_expiry[0] == '\0') {
  87.         nnfree(&hdrs->h_expiry);
  88.         hdrs->h_expiry = strsave(DEFEXP);
  89.     }
  90.     hackoldctl(hdrs);                /* NCMP */
  91. }
  92.  
  93. /*
  94.  * require the headers required by RFC 1036.
  95.  */
  96. char *                    /* error string */
  97. hdrreq(hdrs)
  98. register struct headers *hdrs;
  99. {
  100.     register struct hdrdef **hpp;
  101.     static char errbuf[100];
  102.  
  103.     /* require all required headers and that they have non-empty contents */
  104.     for (hpp = reqdhdrs; *hpp != NULL; hpp++) {
  105.         register char *hdrp = *(char **)((char *)hdrs + (*hpp)->hdroff);
  106.  
  107.         if (hdrp == NULL || hdrp[0] == '\0') {
  108.             (void) sprintf(errbuf, "%s %s header\n",
  109.                 (hdrp == NULL? "no": "empty"), (*hpp)->hdrnm);
  110.             return errbuf;
  111.         }
  112.     }
  113.     return NULL;
  114. }
  115.